package com.uottawa.librarytest.service;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.uottawa.library.dao.BaseDAO;
import com.uottawa.library.dao.ItemDAO;
import com.uottawa.library.dao.LoanDAO;
import com.uottawa.library.dao.UserDAO;
import com.uottawa.library.domain.Item;
import com.uottawa.library.domain.Loan;
import com.uottawa.library.domain.LoanPeriod;
import com.uottawa.library.domain.Item;
import com.uottawa.library.domain.Loan;
import com.uottawa.library.domain.LoanPeriod;
import com.uottawa.library.domain.User;
import com.uottawa.library.service.ItemService;
import com.uottawa.library.service.LoanService;
import com.uottawa.library.service.LoanPeriodService;
import com.uottawa.library.service.LoanService;
import com.uottawa.library.service.TitleService;
import com.uottawa.library.service.UserService;

public class TitleServiceTest {

	private BaseDAO base = new BaseDAO();
	private TitleService titleService = new TitleService();
	private ItemService itemService = new ItemService();
	private LoanService loanService = new  LoanService();
	private LoanDAO loanDAO = new LoanDAO();
	private ItemDAO itemDAO = new ItemDAO();
	private LoanPeriod loanPeriod = new LoanPeriod();

	private UserService userService = new UserService();
	
	@Before
	public void setUp() {
		
		User adminUser = new User(13243, "admin", "password", 0, "admin");
		
		LoanPeriod loanPeriod = new LoanPeriod(1, 5); // initial loan period duration
		LoanPeriod renewal1 = new LoanPeriod(2,10); // first renewal
		LoanPeriod renewal2 = new LoanPeriod(3,10); // Second renewal
		
		LoanPeriodService loanPeriodService = new LoanPeriodService();  //
		loanPeriodService.addPeriod(loanPeriod, adminUser);
		loanPeriodService.addPeriod(renewal1, adminUser);
		loanPeriodService.addPeriod(renewal2, adminUser);
	}

	@After
	public void cleanUp() {
		base.cleanUp();
	}

	@Test
	public void addTitle() {
		assertEquals("success", titleService.addTitle(1752123, "Catcher in the Rye"));
	}

	@Test
	public void addTwoTitles() {
		String result1 = titleService.addTitle(1752123, "Catcher in the Rye");
		String result2 = titleService.addTitle(1752124, "The Destiny");
		boolean check = (result1.equals("success") && result1.equals(result2));
		assertTrue(check);
	}

	@Test
	public void addItem() {
		titleService.addTitle(1752123, "Catcher in the Rye");
		String result = itemService.addItem(1752123);
		assertEquals("success", result);
	}

	@Test
	public void addDuplicateTitles() {
		titleService.addTitle(1752123, "Catcher in the Rye");
		String result2 = titleService.addTitle(1752123, "Catcher in the Rye2");
		assertEquals("failed! duplicate title", result2);
	}

	@Test
	public void addMultiplesOfItems() {

		titleService.addTitle(1752123, "Catcher in the Rye");
		titleService.addTitle(1752124, "The Little Prince");
		titleService.addTitle(1752125, "The Destiny");
		String result1 = itemService.addItem(1752123);
		String result2 = itemService.addItem(1752123);
		String result3 = itemService.addItem(1752123);
		String result4 = itemService.addItem(1752124);
		String result5 = itemService.addItem(1752124);
		String result6 = itemService.addItem(1752125);

		if (result1 == "success" && result2 == "success"
				&& result3 == "success" && result4 == "success"
				&& result5 == "success" && result6 == "success") {
			assertTrue(true);
		} else {
			assertTrue(false);
		}

	}
	
	@Test
	public void removeTitle() {
		titleService.addTitle(1752123, "Catcher in the Rye");
		String result = titleService.removeTitle(1752123);
		assertEquals("success", result);
		assertEquals(0, titleService.getAllTitles().size());
	}
	
	@Test
	public void removeItem() {
		
		Item item = new Item();
		item.setIsbn(32432);
		item.setItemId(123);
		
		ItemDAO itemDao = new ItemDAO();
		itemDao.addItem(item);
		
		boolean result = itemDao.RemoveItem(123);
		assertTrue(result);
	}
	
	@Test
	public void removeItemBeforeBorrowed() {
		UserDAO userDao = new UserDAO();
		LoanService loanService = new LoanService();
		ItemService itemService =new ItemService();
		
		User adminUser =  new User(13243, "admin", "password", 0, "admin");;
		userService.addUser(adminUser);
		
		LoanPeriod loanPeriod = new LoanPeriod(1,5);
		LoanPeriodService loanPeriodService = new LoanPeriodService();
		loanPeriodService .addPeriod(loanPeriod, adminUser);
		
		
		// create user with 0 balance
				User user = new User(11111, "OkUser", "password", 0, "user");
				userDao.addUser(user);

				Item item = new Item();
				item.setItemId(6666);
				itemDAO.addItem(item);

				// insert loan. expect success
				//loanService.borrowLoanCopy(item, user);
		
		String result = itemService.removeItem(item.getItemId());
		assertEquals("success", result);
	}
	
	@Test
	public void removeItemAfterBorrowed() {
		UserDAO userDao = new UserDAO();
		LoanService loanService = new LoanService();
		ItemService itemService =new ItemService();
		
		User adminUser =  new User(13243, "admin", "password", 0, "admin");;
		userService.addUser(adminUser);
		
		LoanPeriod loanPeriod = new LoanPeriod(1,5);
		LoanPeriodService loanPeriodService = new LoanPeriodService();
		loanPeriodService .addPeriod(loanPeriod, adminUser);
		
		
		// create user with 0 balance
				User user = new User(11111, "OkUser", "password", 0, "user");
				userDao.addUser(user);

				Item item = new Item();
				item.setItemId(6666);
				itemDAO.addItem(item);

				// insert loan. expect success
				loanService.borrowLoanCopy(item, user);
		
		String result = itemService.removeItem(item.getItemId());
		assertEquals("failed", result);
	}
	
	
	@Test
	public void removeTitleWithMultipleCopiesSuccess() {
		titleService.addTitle(1752123, "Catcher in the Rye");
		
		// create two copies.
		itemService.addItem(1752123);
		itemService.addItem(1752123);
		
		List<Item> items = itemService.getAllItems();
		
		User user = new User(0, "OkUser", "password", 0, "user");
		userService.addUser(user);
		user = userService.login("OkUser", "password");
		
		// borrow item 1 and item 2
		loanService.borrowLoanCopy(items.get(0), user);
		loanService.borrowLoanCopy(items.get(1), user);

		// retrieve loans from DB to get IDs.
		List<Loan> loans = loanService.getAllLoan();
		Loan loan1 = loans.get(0);
		Loan loan2 = loans.get(1);
		
		loanService.returnLoan(loan1);
		loanService.returnLoan(loan2);
		
		String result = titleService.removeTitle(1752123);
		assertEquals("success", result);
		assertEquals(0, titleService.getAllTitles().size());
	}

	@Test
	public void removeTitleWithMultipleCopiesAndActiveLoans() {
		titleService.addTitle(1752123, "Catcher in the Rye");
		
		// create two copies.
		itemService.addItem(1752123);
		itemService.addItem(1752123);
		
		List<Item> items = itemService.getAllItems();
		
		User user = new User(0, "OkUser", "password", 0, "user");
		userService.addUser(user);
		user = userService.login("OkUser", "password");
		
		// borrow item 1 and item 2
		loanService.borrowLoanCopy(items.get(0), user);
		loanService.borrowLoanCopy(items.get(1), user);

		// retrieve loans from DB to get IDs.
		List<Loan> loans = loanService.getAllLoan();
		Loan loan1 = loans.get(0);
		Loan loan2 = loans.get(1);
		
		// return only loan1
		loanService.returnLoan(loan1);
		
		// removing should fail because of active loans
		String result = titleService.removeTitle(1752123);
		assertEquals("rejected! can't remove a title that is currently loaned", result);
		
		loanService.returnLoan(loan2);
		
		// removing now should succeed.
		result = titleService.removeTitle(1752123);
		assertEquals("success", result);
	}

	
}
